home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / math < prev    next >
Encoding:
Text File  |  1988-04-18  |  15.4 KB  |  577 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              math.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "heap.h"
  14. #include "eq.h"
  15. #include "scan.h"
  16. #include "evalstack.h"
  17. #include "arith.h"
  18. #include "str.h"
  19. #include "box.h"
  20. #include "tfm.h"
  21. #include "print.h"
  22. #include "pack.h"
  23. #include "math.h"
  24.  
  25. twoh    empty_field;
  26.  
  27. ptr
  28. new_style (s)
  29.         int             s;
  30. {
  31.         ptr             p;
  32.  
  33.         p = get_node(STYLE_NODE_SIZE);
  34.         type(p) = STYLE_NODE;
  35.         subtype(p) = s;
  36.         width(p)= 0;
  37.         depth(p) = 0;
  38.  
  39.         return p;
  40. }
  41.  
  42. ptr
  43. new_choice ()
  44. {
  45.         ptr             p;
  46.  
  47.         p = get_node(STYLE_NODE_SIZE);
  48.         type(p) = CHOICE_NODE;
  49.         subtype(p) = 0;
  50.         display_mlist(p) = NULL;
  51.         text_mlist(p) = NULL;
  52.         script_mlist(p) = NULL;
  53.         script_script_mlist(p) = NULL;
  54.  
  55.         return p;
  56. }
  57.  
  58. ptr
  59. new_noad ()
  60. {
  61.         ptr             p;
  62.  
  63.         p = get_node(NOAD_SIZE);
  64.         type(p) = ORD_NOAD;
  65.         subtype(p) = NORMAL;
  66.         mem[nucleus(p)].hh = empty_field;
  67.         mem[subscr(p)].hh = empty_field;
  68.         mem[supscr(p)].hh = empty_field;
  69.  
  70.         return p;
  71. }
  72.  
  73. print_fam_and_char (p)
  74.         ptr             p;
  75. {
  76.         print_esc("fam");
  77.         print_int(fam(p));
  78.         print_char(' ');
  79.         print_ASCII(qo(character(p)));
  80. }
  81.  
  82. print_delimiter (p)
  83.         ptr             p;
  84. {
  85.         val             a;
  86.  
  87.         a = small_fam(p) * 256 + qo(small_char(p));
  88.         a = a * 0x1000 + large_fam(p) * 256 + qo(large_char(p));
  89.         if (a < 0)
  90.                 print_val(a);
  91.         else print_hex(a);
  92. }
  93.  
  94. print_subsidiary_data (p, c)
  95.         ptr             p;
  96.         ascii   c;
  97. {
  98.         if (cur_length() >= depth_threshold) {
  99.                 if (math_type(p) != EMPTY)
  100.                         print(" []");
  101.                 return;
  102.         }
  103.         append_char(c);
  104.         temp_ptr = p;
  105.         switch (math_type(p))
  106.         {
  107.         case MATH_CHAR:
  108.                 print_ln();
  109.                 print_current_string();
  110.                 print_fam_and_char(p);
  111.                 break;
  112.         
  113.         case SUB_BOX:
  114.                 show_info();
  115.                 break;
  116.         
  117.         case SUB_MLIST:
  118.                 if (info(p) == NULL) {
  119.                         print_ln();
  120.                         print_current_string();
  121.                         print("{}");
  122.                 } else show_info();
  123.                 break;
  124.         }
  125.         flush_char();
  126. }
  127.  
  128. print_style (c)
  129.         int       c;
  130. {
  131.         switch (c / 2) 
  132.         {
  133.         case 0:
  134.                 print_esc("displaystyle");
  135.                 break;
  136.  
  137.         case 1:
  138.                 print_esc("textstyle");
  139.                 break;
  140.  
  141.         case 2:
  142.                 print_esc("scriptstyle");
  143.                 break;
  144.  
  145.         case 3:
  146.                 print_esc("scriptscriptstyle");
  147.                 break;
  148.  
  149.         default:
  150.                 print("Unknown style!");
  151.                 break;
  152.         }
  153. }
  154.  
  155. print_size (s)
  156.         int             s;
  157. {
  158.         if (s == 0)
  159.                 print_esc("textfont");
  160.         else if (s == SCRIPT_SIZE)
  161.                 print_esc("scriptfont");
  162.         else print_esc("scriptscriptfont");
  163. }
  164.  
  165. show_normal_noad (p)
  166.         ptr             p;
  167. {
  168.         switch (type(p)) 
  169.         {
  170.         case ORD_NOAD:
  171.                 print_esc("mathord");
  172.                 break;
  173.  
  174.         case OP_NOAD:
  175.                 print_esc("mathop");
  176.                 break;
  177.  
  178.         case BIN_NOAD:
  179.                 print_esc("mathbin");
  180.                 break;
  181.  
  182.         case REL_NOAD:
  183.                 print_esc("mathrel");
  184.                 break;
  185.  
  186.         case OPEN_NOAD:
  187.                 print_esc("mathopen");
  188.                 break;
  189.  
  190.         case CLOSE_NOAD:        
  191.                 print_esc("mathclose");
  192.                 break;
  193.  
  194.         case PUNCT_NOAD:
  195.                 print_esc("mathpunct");
  196.                 break;
  197.  
  198.         case INNER_NOAD:
  199.                 print_esc("mathinner");
  200.                 break;
  201.  
  202.         case OVER_NOAD:
  203.                 print_esc("overline");
  204.                 break;
  205.  
  206.         case UNDER_NOAD:
  207.                 print_esc("underline");
  208.                 break;
  209.  
  210.         case VCENTER_NOAD:
  211.                 print_esc("vcenter");
  212.                 break;
  213.  
  214.         case RADICAL_NOAD:
  215.                 print_esc("radical");
  216.                 print_delimiter(left_delimiter(p));
  217.                 break;
  218.  
  219.         case ACCENT_NOAD:
  220.                 print_esc("accent");
  221.                 print_fam_and_char(accent_chr(p));
  222.                 break;
  223.  
  224.         case LEFT_NOAD:
  225.                 print_esc("left");
  226.                 print_delimiter(nucleus(p));
  227.                 break;
  228.  
  229.         case RIGHT_NOAD:
  230.                 print_esc("right");
  231.                 print_delimiter(nucleus(p));
  232.                 break;
  233.  
  234.         }
  235.         if (subtype(p) != NORMAL)
  236.                 if (subtype(p) == LIMITS)
  237.                         print_esc("limits");
  238.                 else print_esc("nolimits");
  239.         if (type(p) < LEFT_NOAD)
  240.                 print_subsidiary_data(nucleus(p), '.');
  241.         print_subsidiary_data(supscr(p), '^');
  242.         print_subsidiary_data(subscr(p), '_');
  243. }
  244.  
  245. show_fraction_noad (p)
  246.         ptr             p;
  247. {
  248.         print_esc("fraction, thickness ");
  249.         if (thickness(p) == DEFAULT_CODE)
  250.                 print("= default");
  251.         else print_scaled(thickness(p));
  252.         if (small_fam(left_delimiter(p)) != 0 ||
  253.                 small_char(left_delimiter(p)) != MIN_QUARTERWORD ||
  254.                 large_fam(left_delimiter(p)) != 0 ||
  255.                 large_char(left_delimiter(p)) != MIN_QUARTERWORD) {
  256.                 print(", left-delimiter ");
  257.                 print_delimiter(left_delimiter(p));
  258.         }
  259.         if (small_fam(right_delimiter(p)) != 0 ||
  260.                 small_char(right_delimiter(p)) != MIN_QUARTERWORD ||
  261.                 large_fam(right_delimiter(p)) != 0 ||
  262.                 large_char(right_delimiter(p)) != MIN_QUARTERWORD) {
  263.                 print(", right-delimiter ");
  264.                 print_delimiter(right_delimiter(p));
  265.         }
  266.         print_subsidiary_data(numerator(p), '\\');
  267.         print_subsidiary_data(denominator(p), '/');
  268. }
  269.  
  270. show_choice_node (p)
  271.         ptr     p;
  272. {
  273.         print_esc("mathchoice");
  274.         append_char('D');
  275.         show_node_list(display_mlist(p));
  276.         flush_char();
  277.         append_char('T');
  278.         show_node_list(text_mlist(p));
  279.         flush_char();
  280.         append_char('S');
  281.         show_node_list(script_mlist(p));
  282.         flush_char();
  283.         append_char('s');
  284.         show_node_list(script_script_mlist(p));
  285.         flush_char();
  286. }
  287.  
  288. ptr
  289. fraction_rule (t)
  290.         scal    t;
  291. {
  292.         ptr             p;
  293.  
  294.         p = new_rule();
  295.         height(p) = t;
  296.         depth(p) = 0;
  297.  
  298.         return p;
  299. }
  300.  
  301. ptr
  302. overbar (b, k, t)
  303.         ptr             b;
  304.         scal    k;
  305.         scal    t;
  306. {
  307.         ptr             p;
  308.         ptr             q;
  309.  
  310.         p = new_kern(k);
  311.         link(p) = b;
  312.         q = fraction_rule(t);
  313.         link(q) = p;
  314.         p = new_kern(t);
  315.         link(p) = q;
  316.         return (vpack(p, NATURAL));
  317. }
  318.  
  319. ptr
  320. var_delimiter (d, s, v)
  321.         ptr             d;
  322.         int             s;
  323.         scal    v;
  324. {
  325.         ptr             b;
  326.         qword   c;
  327.         fnt             f;
  328.         fnt             g;
  329.         int             m;
  330.         int             n;
  331.         fourq   q;
  332.         fourq   r;
  333.         scal    u;
  334.         scal    w;
  335.         qword   x;
  336.         qword   y;
  337.         int             z;
  338.         byte    hd;
  339.         bool    large_attempt;
  340.  
  341.         f = NULL_FONT;
  342.         w = 0;
  343.         large_attempt = FALSE;
  344.         z = small_fam(d);
  345.         x = small_char(d);
  346.         loop {
  347.                 if (z != 0 || x != MIN_QUARTERWORD) {
  348.                         z = z + s + 16;
  349.                         do {
  350.                                 z = z - 16;
  351.                                 g = fam_fnt(z);
  352.                                 if (g != NULL_FONT) {
  353.                                         y = x;
  354.                         contin:
  355.                                         if (qo(y) >= font_bc[g] && qo(y) <= font_ec[g]) {
  356.                                                 q = char_info(g, y);
  357.                                                 if (char_exists(q)) {
  358.                                                         if (char_tag(q) == EXT_TAG)  {
  359.                                                                 f = g;
  360.                                                                 c = y;
  361.                                                                 goto found;
  362.                                                         }
  363.                                                         hd = height_depth(q);
  364.                                                         u = char_height(g, hd) + char_depth(g, hd);
  365.                                                         if (u > w) {
  366.                                                                 f = g;
  367.                                                                 c = y;
  368.                                                                 w = u;
  369.                                                                 if (u >= v)
  370.                                                                         goto found;
  371.                                                         }
  372.                                                         if (char_tag(q) == LIST_TAG) {
  373.                                                                 y = rem_byte(q);
  374.                                                                 goto contin;
  375.                                                         }
  376.                                                 }
  377.                                         }
  378.                                 }
  379.                         } while (z >= 16);
  380.                 }
  381.                 if (large_attempt)
  382.                         goto found;
  383.                 large_attempt = TRUE;
  384.                 z = large_fam(d);
  385.                 x = large_char(d);
  386.         }
  387.  
  388. found:
  389.         if (f != NULL_FONT) {
  390.                 if (char_tag(q) == EXT_TAG) {
  391.                         b = new_null_box();
  392.                         type(b) = VLIST_NODE;
  393.                         r = font_info[exten_base[f] + rem_byte(q)].qqqq;
  394.                         c = ext_rep(r);
  395.                         u = height_plus_depth(f, c);
  396.                         w = 0;
  397.                         q = char_info(f, c);
  398.                         width(b) = char_width(f, q) + char_italic(f, q);
  399.                         c = ext_bot(r); 
  400.                         if (c != MIN_QUARTERWORD)
  401.                                 w += height_plus_depth(f, c);
  402.                         c = ext_mid(r);
  403.                         if (c != MIN_QUARTERWORD)
  404.                                 w += height_plus_depth(f, c);
  405.                         c = ext_top(r);
  406.                         if (c != MIN_QUARTERWORD)
  407.                                 w += height_plus_depth(f, c);
  408.                         n = 0;
  409.                         if (u > 0) {
  410.                                 while (w < v) {
  411.                                         w = w + u;
  412.                                         incr(n);
  413.                                         if (ext_mid(r) != MIN_QUARTERWORD)
  414.                                                 w = w + u;
  415.                                 }
  416.                         }
  417.                         c = ext_bot(r);
  418.                         if (c != MIN_QUARTERWORD)
  419.                                 stack_into_box(b, f, c);
  420.                         c = ext_rep(r);
  421.                         for (m = 1; m <= n; incr(m)) 
  422.                                 stack_into_box(b, f, c);
  423.                         c = ext_mid(r);
  424.                         if (c != MIN_QUARTERWORD) {
  425.                                 stack_into_box(b, f, c);
  426.                                 c = ext_rep(r);
  427.                                 for (m = 1; m <= n; incr(m))
  428.                                         stack_into_box(b, f, c);
  429.                         }
  430.                         c = ext_top(r);
  431.                         if (c != MIN_QUARTERWORD)
  432.                                 stack_into_box(b, f, c);
  433.                         depth(b) = w - height(b);
  434.                 } else
  435.                         b = char_box(f, c);
  436.         } else {
  437.                 b = new_null_box();
  438.                 width(b) = null_delimiter_space;
  439.         }
  440.         shift_amount(b) = half(height(b) - depth(b)) - axis_height(s);
  441.         return b;
  442. }
  443.  
  444. ptr
  445. char_box (f, c)
  446.         fnt             f;
  447.         qword   c;
  448. {
  449.         ptr             b;
  450.         ptr             p;
  451.         fourq   q;
  452.         byte    hd;
  453.  
  454.         q = char_info(f, c);
  455.         hd = height_depth(q);
  456.         b = new_null_box();
  457.         width(b) = char_width(f, q) + char_italic(f, q);
  458.         height(b) = char_height(f, hd);
  459.         depth(b) = char_depth(f, hd);
  460.         p = get_avail();
  461.         character(p) = c;
  462.         font(p) = f;
  463.         list_ptr(b) = p;
  464.         
  465.         return b;
  466. }
  467.  
  468. stack_into_box (b, f, c)
  469.         ptr             b;
  470.         fnt             f;
  471.         qword   c;
  472. {
  473.         ptr             p;
  474.  
  475.         p = char_box(f, c);
  476.         link(p) = list_ptr(b);
  477.         list_ptr(b) = p;
  478.         height(b) = height(p);
  479. }
  480.  
  481. scal
  482. height_plus_depth (f, c)
  483.         fnt             f;
  484.         qword   c;
  485. {
  486.         fourq   q;
  487.         byte    hd;
  488.  
  489.         q = char_info(f, c);
  490.         hd = height_depth(q);
  491.         return (char_height(f, hd) + char_depth(f, hd));
  492. }
  493.  
  494. ptr
  495. rebox (b, w)
  496.         ptr             b;
  497.         scal    w;
  498. {
  499.         fnt             f;
  500.         ptr             p;
  501.         scal    v;
  502.  
  503.         if (width(b) != w && list_ptr(b) != NULL) {
  504.                 if (type(b) == VLIST_NODE)
  505.                         b = hpack(b, NATURAL);
  506.                 p = list_ptr(b);
  507.                 if (is_char_node(p) && link(p) == NULL) {
  508.                         f = font(p);
  509.                         v = char_width(f, char_info(f, character(p)));
  510.                         if (v != width(b)) 
  511.                                 link(p) = new_kern(width(b) - v);
  512.                 }
  513.                 free_node(b, BOX_NODE_SIZE);
  514.                 b = new_glue(ss_glue);
  515.                 link(b) = p;
  516.                 while (link(p) != NULL)
  517.                         p = link(p);
  518.                 link(p) = new_glue(ss_glue); 
  519.                 return (hpack(b, w, EXACTLY));
  520.         } else {
  521.                 width(b) = w;
  522.                 return b;
  523.         }
  524. }
  525.  
  526. #define mu_mult(x) \
  527.         nx_plus_y(n, x, xn_over_d(x, f, 0200000L))
  528.  
  529. ptr
  530. math_glue (g, m)
  531.         ptr             g;
  532.         scal    m;
  533. {
  534.         scal    f;
  535.         val             n;
  536.         ptr             p;
  537.  
  538.         n = x_over_n(m, 0200000L);
  539.         f = remainder;
  540.         p = get_node(GLUE_SPEC_SIZE);
  541.         width(p) = mu_mult(width(g));
  542.         stretch_order(p) = stretch_order(g);
  543.         if (stretch_order(p) == NORMAL)
  544.                 stretch(p) = mu_mult(stretch(g));
  545.         else stretch(p) = stretch(g);
  546.         shrink_order(p) = shrink_order(g);
  547.         if (shrink_order(p) == NORMAL)
  548.                 shrink(p) = mu_mult(shrink(g));
  549.         else shrink(p) = shrink(g);
  550.  
  551.         return p;
  552. }
  553.  
  554. math_kern (p, m)
  555.         ptr             p;
  556.         scal    m;
  557. {
  558.         scal    f;
  559.         val             n;
  560.  
  561.         if (subtype(p) == MU_GLUE) {
  562.                 n = x_over_n(m, 0200000L);
  563.                 f = remainder;
  564.                 width(p) = mu_mult(width(p));
  565.                 subtype(p) = NORMAL;
  566.         }
  567. }
  568.  
  569. flush_math ()
  570. {
  571.         flush_node_list(link(head));
  572.         flush_node_list(incompleat_noad);
  573.         link(head) = NULL;
  574.         tail = head;
  575.         incompleat_noad = NULL;
  576. }
  577.